package adhoc.tel.fer.hr;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import org.json.JSONException;
import org.json.JSONObject;
import com.acmelabs.inbox.NotificationInbox;
import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.AsyncFacebookRunner.RequestListener;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;

import android.app.Activity;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

/**
 * The main activity with implemented features that are starting point
 * for Bfriend user. Features like login to Facebook, background service,
 * inbox and availability settings are implemented in this class.
 */
public class Main extends Activity implements OnClickListener{
	 
	/** Status bar on the top of the screen.*/
	private TextView mText;
	
	/** Defined space for spinner.*/
	private ListView spinnerSpace;
	
	/** Spinner used in process of login to Facebook and starting background service.*/
	private ProgressDialog facebookSpinner;
	
	/** Instance that can run request to Facebook asynchronously.*/
	private AsyncFacebookRunner facebookRunner;
	
	/** Main instance for communication with Facebook.*/
	private Facebook mFacebook;
	
	/** Request permissions for user information from Facebook.*/
	private static final String[] PERMISSIONS = new String[] {"offline_access" };
	
	/** User ID fetched from Facebook.*/
	private String facebookID;
	
	/** User name fetched from Facebook.*/
	private String facebookName;
	
	/** Infinite access token for connection to Facebook.*/
	private String accessToken;
	
	private MenuItem settingsItem;
	private MenuItem inboxItem;
	private MenuItem myFriendsItem;
	
	/** Stores information about previous login to Facebook.*/
	private boolean isStarted;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        // Initialize fields
        
        PreferencesHelper.initialize(this);
        
        spinnerSpace =  (ListView) Main.this.findViewById( R.id.spinner);     
        
        facebookSpinner = new ProgressDialog(spinnerSpace.getContext());
        facebookSpinner.setMessage("Getting data from Facebook...");
        
        mText = (TextView) Main.this.findViewById(R.id.status);
        mText.setText("Press menu to view options.");
    }
    
    @Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.main_menu, menu);

		return true;
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		
		// Map fields and identified in R.java
		MenuItem loginItem = menu.findItem(R.id.login);
		settingsItem = menu.findItem(R.id.settings);
		inboxItem = menu.findItem(R.id.inbox);
		myFriendsItem = menu.findItem(R.id.myFriends);
		
		loginItem.setTitle("start");
		settingsItem.setTitle("Settings");
		loginItem.setEnabled(true);
		
		// Fetch information about previous app starting by pressing start button
		// TODO Is service running?
		
		isStarted = ServiceTools.isMyServiceRunning(this);
		
		// If app isn't started before, enable only start button
		if (!isStarted){
			inboxItem.setEnabled(false);
			myFriendsItem.setEnabled(false);
			settingsItem.setEnabled(false);
		}
		// Else disable start button, but enable other features.
		else if (isStarted) {
			loginItem.setTitle("Stop");
			inboxItem.setEnabled(true);
			myFriendsItem.setEnabled(true);
			settingsItem.setEnabled(true);
		}

		return super.onPrepareOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		
		// Check what is pressed
		switch (item.getItemId()) {

			case R.id.login:
			if (!isStarted) {
				// Start Facebook login dialog
				getUserFacebookID();
			}
			else{
				stopService(new Intent(Main.this, MainService.class));
			}
				break;
			
			case R.id.inbox:
				// Get the notification inbox
				Intent intent = new Intent(this, NotificationInbox.class);
				startActivity(intent);
				break;	
				
			case R.id.settings:
				// Start settings screen
				Intent settingsActivity = new Intent(this, Settings.class);
				startActivity(settingsActivity);
				break;
			case R.id.myFriends:
				// View lists of friends
				Intent addFriendActivity = new Intent(this, MyFriends.class);
				startActivity(addFriendActivity);
				break;
		}
		return true;
	}
	
	public void registerC2D() {
		Log.w("C2DM", "start registration process");
		
		PreferencesHelper.initialize(this);
		
		Intent intent = new Intent("com.google.android.c2dm.intent.REGISTER");
		intent.putExtra("app",
				PendingIntent.getBroadcast(this, 0, new Intent(), 0));
		// Sender currently not used
		intent.putExtra("sender", "zhidor@gmail.com");
		startService(intent);
	}

	/**
	 * Start Facebook dialog.
	 */
	private void getUserFacebookID() {
		mFacebook = new Facebook("128922667179680");
		facebookRunner = new AsyncFacebookRunner(mFacebook);
		mFacebook.authorize(this, PERMISSIONS, new LoginRequestListener());
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		
		mFacebook.authorizeCallback(requestCode, resultCode, data);
	}
	
	/**
	 * Implements callback interface used to resolve success of request
	 * sent to Facebook. 
	 */
	private class LoginRequestListener implements DialogListener {

		@Override
		public void onComplete(Bundle values) {
			// Login is success, fetch informations about user
			facebookSpinner.show();
			facebookRunner.request("me", new AboutMeRequestListener());
		}

		@Override
		public void onFacebookError(FacebookError e) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onError(DialogError e) {
			Toast.makeText(getApplicationContext(),
					"Login failed: The connection to the Facebook server was unsuccessful.", 3000).show();
        	finish();
			
		}

		@Override
		public void onCancel() {
			// TODO Auto-generated method stub
			
		}
	}
	
	private class AboutMeRequestListener implements RequestListener {

		@Override
		public void onComplete(String response, Object state) {
	        	
				// Informations about user are successfully fetched
			
				JSONObject json;
				try {
					// Get informations from response
					json = new JSONObject(response);
					facebookID = json.getString("id");
					facebookName = json.getString("name");
					accessToken = mFacebook.getAccessToken();
					
					// Store informations to database on phone
					PreferencesHelper.setFacebookID(facebookID);
					PreferencesHelper.setFacebookName(facebookName);
					PreferencesHelper.setAccessToken(accessToken);
					PreferencesHelper.setState("3");
					
					Main.this.runOnUiThread(new Runnable() {
						@Override
						public void run() {
							facebookSpinner.setMessage("Starting service...");
							facebookSpinner.show();
						}
					});
					
					System.out.println("starting_C2D_service...");
					registerC2D();
					
					facebookSpinner.cancel();
						
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
	        }

		@Override
		public void onIOException(IOException e, Object state) {}

		@Override
		public void onFileNotFoundException(FileNotFoundException e, Object state) {}

		@Override
		public void onMalformedURLException(MalformedURLException e, Object state) {}

		@Override
		public void onFacebookError(FacebookError e, Object state) {} 
		
	}

		@Override
		protected void onDestroy() {
			super.onDestroy();
		}

		@Override
		public void onClick(View v) {
			registerC2D();
			
		}
		
}
